package com.examples.master;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.program.Program;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.ExpandBar;
import org.eclipse.swt.widgets.ExpandItem;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Monitor;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;

/**
 * Main executable class to showcase SWT examples.
 * 
 * @author ryada9
 * 
 */
public class MainTable {
	public static void main(String args[]) {

		Display display = Display.getDefault();
		final Shell shell = new Shell(display, SWT.SHELL_TRIM);

		shell.setText("SWT Examples Showcase");
		shell.setLayout(new FillLayout());

		// Create ExpandBar
		ExpandBar bar = new ExpandBar(shell, SWT.V_SCROLL);

		// First Item
		Table dialogExmapleTable = createExamplesTable(bar, createDisplayList());

		ExpandItem item1 = new ExpandItem(bar, SWT.NONE, 0);
		item1.setText("Display Examples...");
		item1.setHeight(dialogExmapleTable
				.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
		item1.setControl(dialogExmapleTable);
		item1.setExpanded(true);

		// Second Item
		Table compositeExmapleTable = createExamplesTable(bar,
				createCompositeList());

		ExpandItem item2 = new ExpandItem(bar, SWT.NONE, 1);
		item2.setText("Composite Examples...");
		item2.setHeight(compositeExmapleTable.computeSize(SWT.DEFAULT,
				SWT.DEFAULT).y);
		item2.setControl(compositeExmapleTable);

		// Third Item
		Table controlExmapleTable = createExamplesTable(bar, createControlList());

		ExpandItem item3 = new ExpandItem(bar, SWT.NONE, 2);
		item3.setText("Control Examples...");
		item3.setHeight(controlExmapleTable
				.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
		item3.setControl(controlExmapleTable);

		// Fourth Item
		Table layoutExmapleTable = createExamplesTable(bar, createLayoutList());

		ExpandItem item4 = new ExpandItem(bar, SWT.NONE, 3);
		item4.setText("Layout Examples...");
		item4.setHeight(layoutExmapleTable
				.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
		item4.setControl(layoutExmapleTable);

		// Fifth Item
		Table graphicsExmapleTable = createExamplesTable(bar, createGraphicsList());

		ExpandItem item5 = new ExpandItem(bar, SWT.NONE, 4);
		item5.setText("Graphics Examples...");
		item5.setHeight(graphicsExmapleTable
				.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
		item5.setControl(graphicsExmapleTable);
		
		//Sixth Item
		
		Table listenersExmapleTable = createExamplesTable(bar, createListenerList());

		ExpandItem item6 = new ExpandItem(bar, SWT.NONE, 5);
		item6.setText("Listener Examples...");
		item6.setHeight(listenersExmapleTable
				.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
		item6.setControl(listenersExmapleTable);
		

		// Set Shell Bounds
		Monitor primary = display.getPrimaryMonitor();
		Rectangle bounds = primary.getBounds();
		Rectangle rect = shell.getBounds();
		int x = bounds.x + Math.max(0, (bounds.width - rect.width) / 2);
		int y = bounds.y + Math.max(0, (bounds.height - rect.height) / 2);
		shell.setBounds(x, y, rect.width, rect.height);

		shell.open();

		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		display.dispose();
	}

	/**
	 * Creates a table in ExpandBar for examples of SWT Display.
	 * 
	 * @param expandBar
	 * @return
	 */
	private static Table createExamplesTable(final Composite expandBar,
			List<ClassVO> classList) {

		final Table tbl = new Table(expandBar, SWT.BORDER | SWT.FULL_SELECTION
				| SWT.V_SCROLL);

		tbl.setLinesVisible(true);		
		tbl.setHeaderVisible(true);

		final TableColumn tc1 = new TableColumn(tbl, SWT.CENTER);
		tc1.setText("S.No.");
		final TableColumn tc2 = new TableColumn(tbl, SWT.CENTER);
		tc2.setText("Class");
		final TableColumn tc3 = new TableColumn(tbl, SWT.CENTER);
		tc3.setText("Description");
		final TableColumn tc4 = new TableColumn(tbl, SWT.CENTER);
		tc4.setText("");

		tbl.addListener(SWT.Resize, new Listener() {
			@Override
			public void handleEvent(Event arg0) {
				Shell shell = (Shell) expandBar.getParent();
				int shellWidth = shell.getClientArea().width;

				tc1.setWidth(shellWidth / 100 * 5);
				tc2.setWidth(shellWidth / 100 * 45);
				tc3.setWidth(shellWidth / 100 * 45);
				tc4.setWidth(shellWidth - shellWidth / 100 * 95);

			}
		});

		Integer i = 1;
		for (final ClassVO exampleClass : classList) {
			final TableItem item = new TableItem(tbl, SWT.NONE);
			item.setText(new String[] { i.toString(),
					exampleClass.getSourceURL() });

			

			Button button = new Button(tbl, SWT.PUSH);
			button.setText("Execute");
			button.computeSize(SWT.DEFAULT, tbl.getItemHeight());
			button.addSelectionListener(new SelectionAdapter() {				

				public void widgetSelected(SelectionEvent event) {
					try {
						@SuppressWarnings("unchecked")
						Method meth = exampleClass.getClassHolder().getMethod(
								"main", String[].class);
						String[] params = null; // init params accordingly
						meth.invoke(null, (Object) params);

					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			});

			
			final StyledText styledTextURL = new StyledText (tbl, SWT.MULTI | SWT.READ_ONLY);
			String url =exampleClass.getSourceURL();
			styledTextURL.setText(url);
			StyleRange style = new StyleRange();
			style.underline = true;
			style.underlineStyle = SWT.UNDERLINE_LINK;
			
			
			
			int[] ranges = {url.indexOf(url), url.length()};
			StyleRange[] styles = {style};
			styledTextURL.setStyleRanges(ranges, styles);
			
			styledTextURL.addMouseListener(new MouseListener() {
				
				@Override
				public void mouseUp(MouseEvent arg0) {
					// TODO Auto-generated method stub
					
				}
				
				@Override
				public void mouseDown(MouseEvent arg0) {
					Program.launch(styledTextURL.getText());
					
				}
				
				@Override
				public void mouseDoubleClick(MouseEvent arg0) {
					// TODO Auto-generated method stub
					
				}
			});
			

			

			TableEditor tblSourceURLText = new TableEditor(tbl);
			tblSourceURLText.grabHorizontal = true;
			// tblSourceURLText.minimumHeight = sourceURL.getSize().y;
			// tblSourceURLText.minimumWidth = sourceURL.getSize().x;
			tblSourceURLText.setEditor(styledTextURL, item, 1);

			Text description = new Text(tbl, SWT.MULTI | SWT.READ_ONLY);
			description.setText(exampleClass.getDescription());

			TableEditor tblEditorText = new TableEditor(tbl);
			tblEditorText.grabHorizontal = true;
			// tblEditorText.minimumHeight = description.getSize().y;
			// tblEditorText.minimumWidth = description.getSize().x;
			tblEditorText.setEditor(description, item, 2);

			TableEditor tblEditor = new TableEditor(tbl);
			tblEditor.grabHorizontal = true;
			tblEditor.minimumHeight = button.getSize().y;
			tblEditor.minimumWidth = button.getSize().x;
			tblEditor.setEditor(button, item, 3);
			
			if (i % 2 == 0) {
				item.setBackground(new Color(tbl.getDisplay(), new RGB(255,
						255, 255)));
				styledTextURL.setBackground(new Color(tbl.getDisplay(), new RGB(255,
						255, 255)));
				description.setBackground(new Color(tbl.getDisplay(), new RGB(255,
						255, 255)));
			} else {
				item.setBackground(new Color(tbl.getDisplay(), new RGB(172,
						212, 252)));
				styledTextURL.setBackground(new Color(tbl.getDisplay(), new RGB(172,
						212, 252)));
				description.setBackground(new Color(tbl.getDisplay(), new RGB(172,
						212, 252)));
			}

			i++;
		}

		return tbl;
	}

	/**
	 * Method to create list of classes.
	 * @return
	 */
	private static List<ClassVO> createDisplayList() {
		List<ClassVO> exampleList = new ArrayList<ClassVO>();// List to hold
		// SWT
		// example
		// classes
		String desc = "Introduction to Shell and Display";
		ClassVO newClass1 = new ClassVO(
				com.examples.helloworld.DisplayBasic.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/helloworld/DisplayBasic.java");
		exampleList.add(newClass1);

		ClassVO newClass2 = new ClassVO(
				com.examples.composite.StringPrompt.class,
				"Prompting for a String",
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/composite/StringPrompt.java");
		exampleList.add(newClass2);

		return exampleList;
	}

	/**
	 * Method to create list of classes.
	 * @return
	 */
	private static List<ClassVO> createCompositeList() {
		List<ClassVO> exampleList = new ArrayList<ClassVO>();// List to hold
		// SWT
		// example
		// classes
		String desc = "Composite Labels and Columns";
		ClassVO newClass1 = new ClassVO(
				com.examples.composite.CompositeEnhanced.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/composite/CompositeEnhanced.java");
		exampleList.add(newClass1);

		desc = "Painting a Composite";
		ClassVO newClass2 = new ClassVO(
				com.examples.composite.PaintComposite.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/composite/PaintComposite.java");
		exampleList.add(newClass2);

		desc = "Calendar Example with Mouse and Keyboard Listeners";
		ClassVO newClass3 = new ClassVO(
				com.examples.calendar.CalendarView.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/calendar/CalendarView.java");
		exampleList.add(newClass3);

		desc = "Calendar Example using Items";
		ClassVO newClass4 = new ClassVO(
				com.examples.calendar.item.CalendarMain.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/calendar/item/CalendarMain.java");
		exampleList.add(newClass4);

		return exampleList;
	}
	
	/**
	 * Method to create list of classes.
	 * @return
	 */
	private static List<ClassVO> createControlList() {
		List<ClassVO> exampleList = new ArrayList<ClassVO>();// List to hold
		// SWT
		// example
		// classes
		String desc = "Combo Box and their types";
		ClassVO newClass1 = new ClassVO(
				com.examples.combobox.ComboBasic.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/combobox/ComboBasic.java");
		exampleList.add(newClass1);

		desc = "Control with various widgets";
		ClassVO newClass2 = new ClassVO(
				com.examples.control.ControlBasic.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/control/ControlBasic.java");
		exampleList.add(newClass2);

		desc = "List with selectable multiple values";
		ClassVO newClass3 = new ClassVO(
				com.examples.list.ListBasic.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/list/ListBasic.java");
		exampleList.add(newClass3);

		desc = "Multi Line Text example";
		ClassVO newClass4 = new ClassVO(
				com.examples.control.MultiLineText.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/control/MultiLineText.java");
		exampleList.add(newClass4);

		desc = "Button inside a Composite";
		ClassVO newClass5 = new ClassVO(
				com.examples.controls.concepts.EnablingBasic.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/controls/concepts/EnablingBasic.java");
		exampleList.add(newClass5);

		desc = "Making Tree Item editable";
		ClassVO newClass6 = new ClassVO(
				com.examples.layouts.TreeItemExample.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/layouts/TreeItemExample.java");
		exampleList.add(newClass6);

		desc = "Menus and Sub Menu example";
		ClassVO newClass7 = new ClassVO(
				com.examples.menu.SubMenuItem.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/menu/SubMenuItem.java");
		exampleList.add(newClass7);

		desc = "Coolbar and Cool Item example";
		ClassVO newClass8 = new ClassVO(
				com.examples.coolbar.CoolItemBasic.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/coolbar/CoolItemBasic.java");
		exampleList.add(newClass8);

		desc = "Open File dialog";
		ClassVO newClass9 = new ClassVO(
				com.examples.filedialog.FileDialogBasic.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/filedialog/FileDialogBasic.java");
		exampleList.add(newClass9);

		desc = "Save files using File dialog";
		ClassVO newClass10 = new ClassVO(
				com.examples.filedialog.FileDialogSave.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/filedialog/FileDialogSave.java");
		exampleList.add(newClass10);

		desc = "Changing text font and size";
		ClassVO newClass11 = new ClassVO(
				com.examples.font.FontDialogBasic.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/font/FontDialogBasic.java");
		exampleList.add(newClass11);

		desc = "Progress Bar example";
		ClassVO newClass12 = new ClassVO(
				com.examples.progressbar.ProgressBarBasic.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/progressbar/ProgressBarBasic.java");
		exampleList.add(newClass12);

		desc = "Progress Bar Scrolling example";
		ClassVO newClass13 = new ClassVO(
				com.examples.progressbar.ProgressBarScrolling.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/progressbar/ProgressBarScrolling.java");
		exampleList.add(newClass13);

		desc = "Slider example with positions identified";
		ClassVO newClass14 = new ClassVO(
				com.examples.slider.SliderEnhanced.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/slider/SliderEnhanced.java");
		exampleList.add(newClass14);

		return exampleList;
	}

	/**
	 * Method to create list of classes.
	 * @return
	 */
	private static List<ClassVO> createLayoutList() {
		List<ClassVO> exampleList = new ArrayList<ClassVO>();// List to hold SWT
																// example
																// classes

		String desc = "Fill Layout example";
		ClassVO newClass1 = new ClassVO(
				com.examples.layouts.FillLayoutExample.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/layouts/FillLayoutExample.java");
		exampleList.add(newClass1);

		desc = "Grid Layout example";
		ClassVO newClass2 = new ClassVO(
				com.examples.layouts.GridLayoutExample.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/layouts/GridLayoutExample.java");
		exampleList.add(newClass2);

		desc = "Row layout example";
		ClassVO newClass3 = new ClassVO(
				com.examples.layouts.RowLayoutExample.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/layouts/RowLayoutExample.java");
		exampleList.add(newClass3);

		desc = "RowData layout example";
		ClassVO newClass4 = new ClassVO(
				com.examples.layouts.RowDataExample.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/layouts/RowDataExample.java");
		exampleList.add(newClass4);

		return exampleList;
	}

	/**
	 * Method to create list of classes.
	 * @return
	 */
	private static List<ClassVO> createGraphicsList() {
		List<ClassVO> exampleList = new ArrayList<ClassVO>();// List to hold SWT
																// example
																// classes

		String desc = "Colour Dialog example";
		ClassVO newClass1 = new ClassVO(
				com.examples.colordialogue.ColourBasic.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/colordialogue/ColourBasic.java");
		exampleList.add(newClass1);

		desc = "Drawing Triangle with Graphics Context";
		ClassVO newClass2 = new ClassVO(
				com.examples.graphics.GraphicsExample.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/graphics/GraphicsExample.java");
		exampleList.add(newClass2);

		desc = "Clipping Region with Graphics Context";
		ClassVO newClass3 = new ClassVO(
				com.examples.graphics.ClippingRegion.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/graphics/ClippingRegion.java");
		exampleList.add(newClass3);

		desc = "Painting Using Graphics Context and resize";
		ClassVO newClass4 = new ClassVO(
				com.examples.painting.PaintingBasic.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/painting/PaintingBasic.java");
		exampleList.add(newClass4);

		desc = "Changing label font and size";
		ClassVO newClass5 = new ClassVO(
				com.examples.font.FontEnhanced.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/font/FontEnhanced.java");
		exampleList.add(newClass5);
		return exampleList;
	}

	/**
	 * Method to create list of classes.
	 * @return
	 */
	private static List<ClassVO> createListenerList() {
		List<ClassVO> exampleList = new ArrayList<ClassVO>();// List to hold SWT
																// example
																// classes

		String desc = "Key Listener in Combo Box";
		ClassVO newClass1 = new ClassVO(
				com.examples.combobox.KeyListenerInCombo.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/combobox/KeyListenerInCombo.java");
		exampleList.add(newClass1);

		desc = "Adding selection listeners on list values";
		ClassVO newClass2 = new ClassVO(
				com.examples.list.ListSelectionListener.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/list/ListSelectionListener.java");
		exampleList.add(newClass2);

		desc = "All Mouse Events and Listeners";
		ClassVO newClass3 = new ClassVO(
				com.examples.mouse.AllMouseEvents.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/mouse/AllMouseEvents.java");
		exampleList.add(newClass3);

		desc = "Key board arrow key events";
		ClassVO newClass4 = new ClassVO(
				com.examples.traversal.CustomTraversal.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/traversal/CustomTraversal.java");
		exampleList.add(newClass4);

		desc = "Resizing Shells and Rectangles";
		ClassVO newClass5 = new ClassVO(
				com.examples.controls.concepts.MoveBasic.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/controls/concepts/MoveBasic.java");
		exampleList.add(newClass5);

		desc = "Moving shells and rectangles";
		ClassVO newClass6 = new ClassVO(
				com.examples.controls.concepts.ResizeEvent.class,
				desc,
				"https://rcpexamples.googlecode.com/svn/trunk/src/com/examples/controls/concepts/ResizeEvent.java");
		exampleList.add(newClass6);

		return exampleList;
	}

}

/**
 * Internal Class to hold examples. 
 * @author ryada9
 *
 */
class ClassVO {
	@SuppressWarnings("rawtypes")
	Class classHolder;
	String description;
	String sourceURL;

	@SuppressWarnings({ "rawtypes" })
	public ClassVO(Class classHolder, String description, String sourceURL) {
		this.classHolder = classHolder;
		this.description = description;
		this.sourceURL = sourceURL;
	}

	@SuppressWarnings("rawtypes")
	public Class getClassHolder() {
		return classHolder;
	}

	public String getDescription() {
		return description;
	}

	public String getSourceURL() {
		return sourceURL;
	}

}
